package cn.cxyxj.sso_client_1.filter;


import cn.cxyxj.code_auth_jwt_persistence_prod.common.ApiResult;
import cn.cxyxj.code_auth_jwt_persistence_prod.common.ApiResultEnum;
import cn.cxyxj.code_auth_jwt_persistence_prod.common.RedisKey;
import cn.cxyxj.code_auth_jwt_persistence_prod.entity.SysUserDetails;
import cn.cxyxj.code_auth_jwt_persistence_prod.utils.RedisUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Objects;

/**
 * 拦截所有请求，判断请求头中是否传递 token 信息
 * @author cxyxj
 */
@Slf4j
public class JwtTokenFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        String requestURI = request.getRequestURI();
        log.info("Request URI = {}", requestURI);
        //从请求头中获取 token
        //String token = request.getHeader("Authorization");
        String token = "";
        HttpSession session = request.getSession();
        Cookie[] cookies = request.getCookies();
        if(cookies != null){
            for(Cookie cookie : cookies){
                if(cookie.getName().equals(RedisKey.SSO_USER_TOKEN)){
                    token = cookie.getValue();
                }
            }
        }

        // 根据 token 从 Redis 获得用户信息
        SysUserDetails sysUserDetails = RedisUtil.get(String.format(RedisKey.TOKEN, token), SysUserDetails.class);
        if (Objects.isNull(sysUserDetails)) {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json;charset=UTF-8");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write(JSONObject.toJSONString(ApiResult.fail(ApiResultEnum.UNAUTHORIZED_ERROR)));
            return;
        }

        // 根据Redis中的用户信息，构建 UsernamePasswordAuthenticationToken 对象，认证状态为 true
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(sysUserDetails, null, sysUserDetails.getAuthorities());
        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        // 设置到 Security 的上下文中
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        chain.doFilter(request, response);

        log.info("Authentication END");
    }
}

